﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using System.Threading;

namespace Magnetism.Crm4.Addons
{
    /// <summary>
    /// Message: Create
    /// Primary Entity: any entity you'd like to automatically increment
    /// Stage of Execution: Pre Stage
    /// Execution Mode: Synchronous
    /// Triggering Pipeline: Parent
    /// </summary>
    public class IncrementalNumberingPlugin : IPlugin
    {
        //private static object _sync = new object(); // Thanks Simon for finding the bug and fix
        private static Mutex _sync = new Mutex(false, "Magnetism.Crm4.Addons.IncrementalNumberingPlugin"); // Thanks grega_g for this fix 

        public IncrementalNumberingPlugin() { }

        public IncrementalNumberingPlugin(string config, string secureConfig) { }

        public void Execute(IPluginExecutionContext context)
        {
            if (context.InputParameters.Properties.Contains("Target") &&
                context.InputParameters.Properties["Target"] is DynamicEntity)
            {
                DynamicEntity entity = context.InputParameters.Properties["Target"] as DynamicEntity;

                _sync.WaitOne();

                // simple query to get incremental settings for this entity
                using (ICrmService service = context.CreateCrmService(true))
                {
                    try
                    {
                        IncrementalNumbering setting = IncrementalNumbering.GetSettings(service, entity.Name);

                        // system generated, if its assigned ignore this record
                        if (setting != null && !entity.Properties.Contains(setting.PropertyName))
                        {
                            int next = setting.CurrentPosition + 1;
                            CrmNumberProperty increment = new CrmNumberProperty(setting.PropertyName, new CrmNumber(next));
                            entity.Properties.Add(increment);

                            // keep track of the latest id inside the custom entity
                            setting.Increment(service, next);
                        }
                    }
                    catch { } // TODO: add error loggin, catch all to make sure lock is released
                }

                _sync.ReleaseMutex();
            }
        }
    }
}
